#!/usr/bin/python
# POLITEIA_LICENSE

import ogre.io.OIS as OIS
import ogre.gui.CEGUI as CEGUI

XAXIS, YAXIS, ZAXIS = xrange(3)

def _convert_ois_mouse_button_to_cegui(buttonId):
    if buttonId == 0:
        return CEGUI.LeftButton
    elif buttonId == 1:
        return CEGUI.RightButton
    elif buttonId == 2:
        return CEGUI.MiddleButton
    elif buttonId == 3:
        return CEGUI.X1Button
    else:
        return CEGUI.LeftButton

class InputManager(OIS.MouseListener, OIS.KeyListener, OIS.JoyStickListener):
    Mouse = None
    Keyboard = None
    Joy = None
    
    def __init__(self, path, wnd_handler_string):
        OIS.MouseListener.__init__(self)
        OIS.KeyListener.__init__(self)
        OIS.JoyStickListener.__init__(self)

        self.Manager = OIS.createPythonInputSystem([('WINDOW', wnd_handler_string)])
        
        self._init_inputs()
        
    def __del__(self):
        if self.Keyboard:
            self.Manager.destroyInputObjectKeyboard(self.Keyboard)
        if self.Mouse:
            self.Manager.destroyInputObjectMouse(self.Mouse)
        # self.Joystick
        OIS.InputManager.destroyInputSystem(self.Manager)
        
    def _init_inputs(self):
        self._init_keyboard()
        self._init_mouse()
        #self._init_joystick()
        self._init_action_map()
        
    def _init_keyboard(self):
        if self.Manager.getNumberOfDevices(OIS.OISKeyboard) > 0:
            self.Keyboard = self.Manager.createInputObjectKeyboard(
                    OIS.OISKeyboard, True)
            self.Keyboard.setEventCallback(self)
            
    def _init_mouse(self):
        if self.Manager.getNumberOfDevices(OIS.OISMouse) > 0:
            self.Mouse = self.Manager.createInputObjectMouse(OIS.OISMouse, True)
            self.Mouse.setEventCallback(self)
            
    def _init_action_map(self):
        self.KeyActionMap = {}
        self.MouseButtonMap = {}
        self.MouseAxisMap = {}
        
    def set_window_resolution(self, width, height):
        if self.Mouse:
            st = self.Mouse.getMouseState()
            st.width = width
            st.height = height

    def update(self):
        if self.Keyboard:
            self.Keyboard.capture()
            
        if self.Mouse:
            self.Mouse.capture()
            
    def register_key_event(self, key, method):
        self.KeyActionMap[key] = method
        
    def unregister_key_event(self, key):
        if self.KeyActionMap.has_key(key):
            self.KeyActionMap.pop(key)
            
    def register_mouse_axis_event(self, axis, method):
        self.MouseAxisMap[axis] = method
        
    def unregister_mouse_axis_event(self, axis):
        if self.MouseAxisMap.has_key(axis):
            self.MouseAxisMap.pop(axis)
            
    def register_mouse_button_event(self, button, method):
        self.MouseButtonMap[button] = method
    
    def unregister_mouse_button_event(self, button):
        if self.MouseButtonMap.has_key(button):
            self.MouseButtonMap.pop(button)
            
    def mouseMoved(self, evt):
        x = evt.get_state().X.rel
        y = evt.get_state().Y.rel
        z = evt.get_state().Z.rel
        CEGUI.System.getSingleton().injectMouseMove(x, y)
        if x != 0:
            if self.MouseAxisMap.has_key(XAXIS):
                self.MouseAxisMap[XAXIS](x)
        if y != 0:
            if self.MouseAxisMap.has_key(YAXIS):
                self.MouseAxisMap[YAXIS](y)
        if z != 0:
            CEGUI.System.getSingleton().injectMouseWheelChange(z)
            if self.MouseAxisMap.has_key(XAXIS):
                self.MouseAxisMap[XAXIS](z)
        return True
        
    def mousePressed(self, evt, id):
        CEGUI.System.getSingleton().injectMouseButtonDown(
                _convert_ois_mouse_button_to_cegui(id))
        if self.MouseButtonMap.has_key(id):
            self.MouseButtonMap[id](id, evt.state.X.abs, evt.state.Y.abs, True)
        return True
   
    def mouseReleased(self, evt, id):
        CEGUI.System.getSingleton().injectMouseButtonUp(
                _convert_ois_mouse_button_to_cegui(id))
        if self.MouseButtonMap.has_key(id):
            self.MouseButtonMap[id](id, evt.state.X.abs, evt.state.Y.abs, False)
        return True
        
    def keyPressed(self, evt):
        CEGUI.System.getSingleton().injectChar(evt.text)
        CEGUI.System.getSingleton().injectKeyDown(evt.key)
        if self.KeyActionMap.has_key(evt.key):
            self.KeyActionMap[evt.key](evt.key, True)
        return True
        
    def keyReleased(self, evt):
        CEGUI.System.getSingleton().injectKeyUp(evt.key)
        if self.KeyActionMap.has_key(evt.key):
            self.KeyActionMap[evt.key](evt.key, false)
        return True
 
